#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <pthread.h>
#define THREAD_ERROR_CHECK(ret, msg)              \
    {                                             \
        if (ret != 0)                             \
        {                                         \
            fprintf(stderr,"%s:%s", msg, strerror(ret)); \
        }                                         \
    }
#define ARGS_CHECK(argc, num)               \
    {                                       \
        if (argc != num)                    \
        {                                   \
            fprintf(stderr, args error !n); \
            return -1;                      \
        }                                   \
    }
#define ERROR_CHECK(ret, num, msg) \
    {                              \
        if (ret == num)            \
        {                          \
            perror(msg);           \
            exit(1);               \
        }                          \
    }
void *my_msgrcv(void *arg);
void *my_msgsnd(void *arg);
int main(int argc, char *argv[])
{
    // 创建套接字
    int fd_s = socket(PF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(-1, fd_s, "socket");
    // 设置自己IP port
    struct sockaddr_in saddr, caddr;
    saddr.sin_family = PF_INET;
    saddr.sin_port = htons(8888);
    saddr.sin_addr.s_addr = inet_addr("0");
    // 绑定
    int ret = bind(fd_s, (void *)&saddr, sizeof saddr);
    ERROR_CHECK(-1, ret, "bind");
    // 监听队列大小
    ret = listen(fd_s, 2);
    ERROR_CHECK(-1, ret, "listen");
    puts("listen ....");
    // 等待连接
    int len = sizeof caddr;
    int new_fd = accept(fd_s, (void *)&caddr, &len);
    ERROR_CHECK(new_fd, -1, "accept");
    // 创建两个线程分别进行数据收发；
    pthread_t tid_r, tid_s;
    ret = pthread_create(&tid_r, NULL, my_msgrcv, &new_fd);
    THREAD_ERROR_CHECK(ret,"pthread_create");
    ret = pthread_create(&tid_r, NULL, my_msgsnd, &new_fd);
    THREAD_ERROR_CHECK(ret,"pthread_create");

    pthread_detach(tid_r);
    pthread_detach(tid_s);
    while (1)
    {
        sleep(1);
    }

    return 0;
}
void *my_msgrcv(void *arg)
{
    int fd = *(int *)arg, ret;
    char buf[128];
    while (1)
    {
        ret = read(fd, buf, 128);
        if (-1 == ret)
        {
            perror("read");
            exit(-1);
        }
        else if (0 == ret)
        {
            exit(0);
        }
        if (0 == strcasecmp(buf, "quit\n"))
        {
            exit(0);
        }
        puts(buf);
    }
}
void *my_msgsnd(void *arg)
{
    int fd = *(int *)arg, ret;
    char buf[128];
    while (1)
    {
        fgets(buf,128,stdin);
        if (0 >= write(fd,buf,128))
        {
            exit(0);
        }
        if (0 == strcasecmp(buf,"quit\n"))
        {
            exit(0);
        }
        
        
    }
}